{------------------------------------------------------------------------------
#
#	Apple Macintosh Developer Technical Support
#
#	"Skippy White's Famous High Level Off-Screen Map RoutinesÓ
#
#	Offscreen.p		-	Pascal Header
#
#	Copyright © 1989 Apple Computer, Inc.
#	All rights reserved.
#	The characters depicted herein (except Skippy White) are fictitious.
#
#	Versions:	
#				1.00				04/89
#
#	Components:
#				Offscreen.p			April 1, 1988
#				Offscreen.inc1.p	April 1, 1988
#
#	These routines provide a high-level interface to the QuickDraw & Color
#	Manager routines which allow the creation and manipulation of off-screen
#	bitmaps and pixmaps. They are designed to run on any machine with 128K or
#	later ROMs (sorry 64K ROM fans).
#	Note that the design incorporates the idea that you can go along pretending
#	there is an offscreen buffer even when one couldnŐt be allocated, and the
#	calls will do nothing.
#
-------------------------------------------------------------------------------}

UNIT Offscreen;


INTERFACE



	USES MemTypes, QuickDraw, OSIntf, ToolIntf;



CONST
	noDeviceIntersectErr = -6969;

	kMaxDepth = 0;
	
	kOffscreenReserve = 8196;

TYPE
	BitMapHandle	= ^BitMapPtr;
	BitMapPtr		= ^BitMap;



{Must be called before any routines of the unit are used.}

PROCEDURE InitOffscreen;


 
{Create an off-screen pixel map for drawing into and then bltting elsewhere.}

FUNCTION NewOffscreen(bounds: Rect; depth: INTEGER; colors: CTabHandle;
					  memoryPolite: BOOLEAN; VAR buffNotNeeded: BOOLEAN; VAR offscreenHandle: Handle): OSErr;

{	Memory Manager errors may occur. In addition, if the requested depth is
	not supported by QuickDraw, memFullErr will be returned.

	bounds:
		The bounds rectangle to be used for the pixmap (in global coordinates).
	This will often be the same as the bounding rectangle of a port or window
	to be used. It must be in global coordinates, however, so you can't (directly)
	use a window's portRect.

	The bounds will be offset so that topLeft is at (0, 0) before setting up the
	off-screen port. The global version will be stored as the requested bounds,
	and updated by calls to MoveOffscreen.

		NOTE: if you'll pass in a depth > 0, you can use a "local" boundsRect.

	depth:
		The desired pixel depth of the map. Use kMaxDepth (0) if you want the
	maximum depth device for the (global) bounds rectangle.

	colors: (only applies if depth > 0; ignored otherwise)
		The color table you want the off-screen pixmap to have. If you pass in NIL
	the color table from the System or ROM (for that depth) will be used.

	memoryPolite:
		If true, the bits will be kept in a purgeable block. If it gets purged, then
	CheckOffscreen or CheckBoundsOffscreen will reallocate it and a redraw will be needed.

	offscreenHandle:
		The new handle to the (private) data is returned in offscreenHandle.

	A new graphics device will be created if requestedDepth > 0. NewHandle will
	be used to allocate storage for the actual pixels.
}



{Dispose of the entire off-screen data structure.}

PROCEDURE DisposeOffscreen(offscreenHandle: Handle);



{Prepare to draw to an off-screen port and map. The port and handle to the bits
 will be locked down. If you donŐt have a specific port you want to use, pass
 in NIL for port and the private one for this buffer will be used.
 Although you can use this for a buffered window and pass in the WindowPtr,
 you would normally use BeginUpdateOffscreen instead (see below).}

PROCEDURE BeginOffscreenDrawing(offscreenHandle: Handle; port: GrafPtr);



{Call this when through drawing to the off-screen map. Must match a previous
 StartDO call, of course. }

PROCEDURE EndOffscreenDrawing(offscreenHandle: Handle);



{Check to see if the depth or color table of the principal graphic device
 associated with the bits has changed. Call this when you get an update event
 that relates to this buffer, and if you have some idle time and want to redraw
 any part of the offscreen map that is invalid.
 
 For buffered windows, call this right before you call BeginUpdateOffscreen; donŐt
 skip the Begin- EndUpdateOffscreen stuff even if drawNeeded returns FALSE.
 
 drawNeeded will return TRUE if you need to redraw the contents of the map.
 The result, if <> noErr, will usually be a Memory Manager error indicating that
 the block of bits for a new (greater) depth couldn't be allocated.}

FUNCTION CheckOffscreen(offscreenHandle: Handle; VAR drawNeeded: BOOLEAN): OSErr;



{Call this when the rectangle of the off-screen map needs to change, perhaps
 due to a window moving on the main screen. This will also check for any change
 in depth.
 drawNeeded will return TRUE if you need to redraw the contents of the map.
 The result, if <> noErr, will usually be a Memory Manager error indicating that
 the block of bits for a new (greater) size (or depth) couldn't be allocated.}

FUNCTION CheckBoundsOffscreen(offscreenHandle: Handle; newBounds: Rect;
					   VAR drawNeeded: BOOLEAN): OSErr;



{When buffering the contents of a window, use this instead of ValidRect.
 If offscreenHandle isnŐt a buffer for a window, pass in NIL for the window parameter.}

PROCEDURE ValidRectOffscreen(offscreenHandle: Handle; window: WindowPtr; validRect: Rect);



{When buffering the contents of a window, use this instead of ValidRgn.
 If offscreenHandle isnŐt a buffer for a window, pass in NIL for the window parameter.}

PROCEDURE ValidRgnOffscreen(offscreenHandle: Handle; window: WindowPtr; validRegion: RgnHandle);



{When buffering the contents of a window, use this instead of InvalRect.
 If offscreenHandle isnŐt a buffer for a window, pass in NIL for the window parameter.}

PROCEDURE InvalRectOffscreen(offscreenHandle: Handle; window: WindowPtr; invalidRect: Rect);



{When buffering the contents of a window, use this instead of InvalRgn.
 If offscreenHandle isnŐt a buffer for a window, pass in NIL for the window parameter.}

PROCEDURE InvalRgnOffscreen(offscreenHandle: Handle; window: WindowPtr; invalidRgn: RgnHandle);



{Get a map pointer, suitable for CopyBits. Note that neither the map
 itself, nor the bits pointed to are locked down. Thus this map, and
 the bits pointed to by GetMap^.baseAddr will move. Also note that this
 will be a BitMapPtr for Classic QD systems, and will be a PixMapPtr
 for Color QD systems. NIL will be returned if there are no bits. It
 may be possible to re-allocate them with CheckOffscreen.}

FUNCTION GetMap(offscreenHandle: Handle): BitMapPtr;



{Returns a handle to the bits. NIL means either that it got purged, or
 that the bits arenŐt in a heap block after all.}

FUNCTION GetBitsHandle(offscreenHandle: Handle): Handle;



{---------- Here are routines specific to buffered windows ----------}
	

{Create an off-screen pixel map for a port.
 It will always use kMaxDepth and always be memoryPolite (???and shouldnŐt return buffNotNeeded?).}

FUNCTION NewOffscreenForWindow(window: WindowPtr; VAR buffNotNeeded: BOOLEAN;
							   VAR offscreenHandle: Handle): OSErr;



{When buffering a window you should use this instead of BeginUpdate. The visRgn
 will be setup properly. window must be a valid window (donŐt pass in NIL).
 Call EndUpdateOffscreen when you are through drawing.}
 
PROCEDURE BeginUpdateOffscreen(offscreenHandle: Handle; window: WindowPtr);



{The sequence is BeginUpdateOffscreen, draw, EndUpdateOffscreen}

PROCEDURE EndUpdateOffscreen(offscreenHandle: Handle; window: WindowPtr);




IMPLEMENTATION

{$I Offscreen.inc1.p}

END.
